package com.ll.common.core.interceptor;

import com.ll.common.core.annotation.NoLogin;
import com.ll.common.core.common.JwtUtils;
import com.ll.common.core.ex.BusinessException;
import com.ll.common.core.utils.TokenUtils;
import com.ll.common.core.utils.UserUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Component
@Slf4j
public class AuthInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private TokenUtils tokenUtils;
    @Autowired
    private UserUtils userUtils;

    /**
     * 前置拦截
     * 参数3: handler就是目标方法
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /*
         * 拦截请求
         * 1. 目标方法上是否有@NoLogin注解,如果有,直接放行
         * 2. 如果没有这个注解,从请求头获得令牌
         * 3. 解析令牌
         * 4. 如果解析正常,放行
         * 5. 如果解析失败,则不放行
         */
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            log.debug("获取拦截的目标方法 method {}", method);

            // 获得注解的方式1:
            // // 判断访问的控制层方法是否使用了注解
            // boolean ret = method.isAnnotationPresent(NoLogin.class);
            // // 如果存在，直接放行
            // if (ret) {
            //     return true;
            // }

            // 获得注解的方式2:
            NoLogin annotation = method.getAnnotation(NoLogin.class);
            if (!ObjectUtils.isEmpty(annotation)) {
                log.debug("目标方法: {},可以放行", method.getName());
                return true;
            }

            String token = request.getHeader("token");
            if (!StringUtils.hasText(token)){
                throw new BusinessException("没有身份信息,请登录后再试!");
            }
            try {
//                Claims claims = jwtUtils.parseToken(token);
                Integer uid = tokenUtils.getUserIdFromToken();
                userUtils.setUId(uid);
                //
                return true;
            }catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("令牌过期,请重新登录!");
            }

        }
        return true;
    }
}
